/*
 * BirthdayList.cpp
 *
 *  Created on: 22.04.2009
 *      Author: h3llfire
 */

#include "BirthdayList.h"
#include "../../core/Impp.h"

namespace Impp {

BEGIN_EVENT_TABLE(BirthdayList, wxFrame)
	EVT_BUTTON(ID_UPDATE, BirthdayList::onUpdate)
END_EVENT_TABLE()



int wxCALLBACK BirthdayListCompareFunction(long item1, long item2, long sortData){
	BirthdayList* list = (BirthdayList*)sortData;
	return list->compareFunction(item1,item2);
}


Birthdate::Birthdate(int day, int month, int year) :
	day(day),
	month(month),
	year(year){}

Birthdate::Birthdate(Buddy* buddy){
	wxString tmp = buddy->getExtendedInfo(BUDDY_EXT_BIRTH_YEAR);

	if(tmp.IsEmpty() || tmp == wxT("0")){
		this->year = 0;
		this->month = 0;
		this->day = 0;
		return;
	}

	long lTmp;
	tmp.ToLong(&lTmp);
	this->year = lTmp;
	tmp = buddy->getExtendedInfo(BUDDY_EXT_BIRTH_MONTH);
	tmp.ToLong(&lTmp);
	this->month = lTmp;
	tmp = buddy->getExtendedInfo(BUDDY_EXT_BIRTH_DAY);
	tmp.ToLong(&lTmp);
	this->day = lTmp;
}

int Birthdate::compare(const Birthdate & bd) const{
	if(bd.year == 0 && this->year == 0){
		return 0;
	}
	if(bd.year == 0){
		return -1;
	}
	if(this->year == 0){
		return 1;
	}
	if(this->year < bd.year){
		return -1;
	}else if(this->year > bd.year){
		return 1;
	}
	if(this->month < bd.month){
		return -1;
	}else if(this->month > bd.month){
		return 1;
	}
	if(this->day < bd.day){
		return -1;
	}else if(this->day > bd.day){
		return 1;
	}
	return 0;
}

wxString Birthdate::getAsString() const{
	if(year == 0){
		return wxT("-");
	}
	wxString buf;
	buf.Printf(wxT("%i.%i.%i"), day,month,year);
	return buf;
}

int Birthdate::getDaysLeft(const wxDateTime & today) const{
	if(year == 0){
		return -1;
	}
	wxDateTime bd(day, (wxDateTime::Month) (month-1),today.GetYear(),0,0,0,0);

	if(!bd.IsLaterThan(today)){
		bd.SetYear(today.GetYear()+1);

	}
	wxTimeSpan span = bd - today;
	return span.GetDays();
}

IMPLEMENT_DYNAMIC_CLASS(StdBirthdayModule, iModule)

BirthdayList::BirthdayList(wxWindow* win) :
	wxFrame(win,wxID_ANY,wxT("Birthdaylist")){

	wxPanel* mainPane = new wxPanel(this);
	wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL);

	list = new wxListCtrl(mainPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT|wxLC_HRULES|wxLC_VRULES);

	wxListItem buddyNameColumn;
	buddyNameColumn.SetText(wxT("Name"));
	buddyNameColumn.SetImage(-1);
	list->InsertColumn(0, buddyNameColumn);

	wxListItem buddyBirthdayColumn;
	buddyBirthdayColumn.SetText(wxT("Birthday"));
	buddyBirthdayColumn.SetImage(-1);
	list->InsertColumn(1, buddyBirthdayColumn);

	wxListItem daysLeftColumn;
	daysLeftColumn.SetText(wxT("Days left"));
	daysLeftColumn.SetImage(-1);
	list->InsertColumn(2, daysLeftColumn);

	std::vector<Buddy*> buddies = Impp::exemplar()->getAllBuddies();

	wxDateTime now = wxDateTime::Now();

	//wxLogDebug(wxT("%i.%i.%i"), now.GetDays(), now.GetMonths(), now.GetYears());


	for(size_t i = 0; i < buddies.size(); i++){
		Buddy* buddy = buddies[i];

		Birthdate bd(buddy);

		long itemId = list->InsertItem(i,buddy->getName());
		list->SetItemPtrData(itemId, (wxUIntPtr)buddy);
		list->SetItem(itemId,1,bd.getAsString());
		list->SetItem(itemId,2,wxString::Format(wxT("%i"),bd.getDaysLeft(now)));
	}

	list->SetColumnWidth( 0, wxLIST_AUTOSIZE );
	list->SetColumnWidth( 1, wxLIST_AUTOSIZE );
	list->SetColumnWidth( 2, wxLIST_AUTOSIZE );

	list->SortItems(BirthdayListCompareFunction, (long)this);


	wxButton* btnUpdate = new wxButton(mainPane,ID_UPDATE, wxT("Update"));

	mainSizer->Add(list, 1, wxALL|wxEXPAND,5);
	mainSizer->Add(btnUpdate, 0, wxALL, 5);

	mainPane->SetSizer(mainSizer);
	mainPane->Layout();

	Layout();
	Show();

	Impp::exemplar()->Connect(wxID_ANY,EVT_BUDDY_CHANGED, BuddyChangedEventHandler(BirthdayList::onBuddyChanged), NULL, this);

}

BirthdayList::~BirthdayList() {

}

void BirthdayList::onUpdate(wxCommandEvent & event){
	std::vector<Buddy*> buddies = Impp::exemplar()->getAllBuddies();
	Impp* impp = Impp::exemplar();

	for(size_t i = 0; i < buddies.size(); i++){
		Buddy* b = buddies[i];

		wxString tmp = b->getExtendedInfo(BUDDY_EXT_BIRTH_YEAR);

		if(tmp.IsEmpty() || tmp == wxT("0")){
			impp->requestFullUserInfo(b);
		}
	}
}

void BirthdayList::onBuddyChanged(BuddyChangedEvent & event){
	if(event.getChangeType() ==  BUDDY_CHANGED_FULL_USERINFO){
		for(int i = 0; i < list->GetItemCount(); i++){
			Buddy* b = (Buddy*)list->GetItemData(i);
			if(b == event.getBuddy()){
				Birthdate bd(b);

				wxDateTime now = wxDateTime::Now();
				list->SetItem(i,1,bd.getAsString());
				list->SetItem(i,2,wxString::Format(wxT("%i"),bd.getDaysLeft(now)));
				list->SortItems(BirthdayListCompareFunction, (long)this);

				break;
			}
		}
	}
	event.Skip();
}

int BirthdayList::compareFunction(long item1, long item2){

	Buddy* buddy1 = (Buddy*)item1;
	Buddy* buddy2 = (Buddy*)item2;

	Birthdate date1(buddy1);
	Birthdate date2(buddy2);

	return date1.compare(date2);
}

void StdBirthdayModule::moduleInit(){
	Impp* impp = Impp::exemplar();
	impp->Connect(wxID_ANY,EVT_IMPP_COMMAND, ImppCommandEventHandler(StdBirthdayModule::onImppCommand), NULL, this);

	//create Mainmenu entry
	iUserInterface* ui = impp->getModuleManager()->getUserInterfaceModule();
	if(ui != NULL){
		ui->reigsterMainMenuEntryAdder(STD_BIRTHDAYLIST_MODULE_NAME, StdBirthdayModule::addMainMenuItem);
	}else{
		wxLogDebug(wxT("StdBirthdayEvtHandler: No UserInterface found to add MainMenu entry!"));
	}
}

void StdBirthdayModule::moduleDestroy(){
	Impp* impp = Impp::exemplar();
	impp->Disconnect(wxID_ANY,EVT_IMPP_COMMAND, ImppCommandEventHandler(StdBirthdayModule::onImppCommand), NULL, this);
}

void StdBirthdayModule::onImppCommand(ImppCommandEvent & event){
	if(event.getModuleName() == STD_BIRTHDAYLIST_MODULE_NAME){
		if(event.getActionName() == STD_BIRTHDAYLIST_ACTION_SHOW){

			iBuddyList* buddyList = Impp::exemplar()->getModuleManager()->getBuddyListModule();
			if(buddyList!=NULL){
				new BirthdayList(buddyList->getWindow());
			}else{
				wxLogError(wxT("Coudn't load BirthdayModule, no BuddylistModule loaded"));
			}

		}
	}else{
		event.Skip();
	}
}

void wxCALLBACK StdBirthdayModule::addMainMenuItem(iMenu* menu, void* ptr){
	menu->appendItem(STD_BIRTHDAYLIST_ACTION_SHOW, wxT("Birthdaylist"), 70, wxT("show Birthdaylist"));
}

}
